package dataStrcture;


import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 求子树的最小值HiHoCoder 1576
 * Created by shuowu on 2017/9/17.
 */
public class SubTreeMax {

    private class TreeNode {
        TreeNode left;
        TreeNode right;
        //在数组中的下标
        int value;

        TreeNode(int value) {
            this.value = value;
        }
    }

    private static final int MAX = 100010;
    private static final int MAX_NUMBER = 1000000001;

    private int[] values = new int[MAX];

    //因为可能不是二叉树，所以存储边
    private List<List<Integer>> edge = new ArrayList<>();

    //记录每个结点的子节点的区间
    private int[] start = new int[MAX];
    private int[] end = new int[MAX];

    private int[] segmentTree = new int[MAX << 2];
    int tim = 0;

    private int num;

    public static void main(String[] args) {
        SubTreeMax object = new SubTreeMax();
        object.getRes();
    }


    private void getRes() {
        Scanner scanner = new Scanner(new BufferedInputStream(System.in));
        while (scanner.hasNext()) {
            num = scanner.nextInt();
            edge.add(new ArrayList<Integer>());
            for (int i = 1; i <= num; i++) {
                values[i] = scanner.nextInt();
                edge.add(new ArrayList<Integer>());
            }
            //第一个结点是根结点
            for (int i = 2; i <= num; i++) {
                int u = scanner.nextInt();
                edge.get(u).add(i);
            }
            dfs(1);
//            for (int i = 1; i <= num; i++) {
//                System.out.println("cur node" + i + " start:" + start[i] + " end:" + end[i]);
//            }
            init();
            for (int i = 1; i <= num; i++) {
                update(1, 1, num, start[i], values[i]);
            }
            int changeCount = scanner.nextInt();
            while (changeCount-- > 0) {
                //System.out.println("count:" + changeCount);
                int type = scanner.nextInt();
                int pos = scanner.nextInt();
                int val;
                if (type == 1) {
                    val = scanner.nextInt();
                    update(1, 1, num, start[pos], val);
                } else {
                    //如果是查询
                    System.out.printf("%d\n", query(1, 1, num, start[pos], end[pos]));
                }
            }
        }
        scanner.close();
    }

    private void init() {
        //4倍
        int segmentLength = num << 2;
        for (int i = 1; i <= segmentLength; i++) {
            segmentTree[i] = MAX_NUMBER;
        }
    }

    private void build(TreeNode node) {
        if (node.left == null && node.right == null) {
            segmentTree[node.value] = node.value;
            return;
        }
        build(node.left);
        build(node.right);
        // 这个根据具体情况具体写，题目上是求和，所以这里是加左右子树的值
        // 如果变成最大值，那么这儿应该相应的改成最大值
        segmentTree[node.value] = Math.min(segmentTree[node.left.value],
                segmentTree[node.right.value]);
    }


    //用dfs序预处理出来以i为根的子树区间为l[i]~r[i]
    //从1到n
    public void dfs(int u) {
        start[u] = ++tim;
        //获取u的所有边
        for (int v : edge.get(u)) {
            dfs(v);
        }
        end[u] = tim;
    }

    //更新, index指的是线段树的下标
    //left和right需要更新的数组中的边界
    //更新x的值为y
    public void update(int index, int left, int right, int x, int y) {
        if (left == right) {
            segmentTree[index] = y;
            return;
        }
        int mid = (left + right) >> 1;
        // 寻找到x所对应的tree[num]
        if (x <= mid) {
            update(index << 1, left, mid, x, y);
        } else {
            update(index << 1 | 1, mid + 1, right, x, y);
        }
        segmentTree[index] = Math.min(segmentTree[index << 1], segmentTree[index << 1 | 1]);
    }

    public int query(int index, int left, int right, int x, int y) {
        // 此时tree[index]就已经是这一部分的有效数据了，所以直接return即可
        if (x <= left && y >= right) {
            return segmentTree[index];
        }
        int mid = (left + right) >> 1;
        int leftMin = MAX_NUMBER;
        int rightMin = MAX_NUMBER;
        if (x <= mid)
            leftMin = query(index << 1, left, mid, x, y);
        if (y > mid)
            rightMin = query(index << 1 | 1, mid + 1, right, x, y);
        return Math.min(leftMin, rightMin);
    }
}
